﻿/*-----------------------------------------------
// File: OnceAttackPackage.cs
// Description: 输出包相关，包括结构、方法
// Author: Shaobing	492057342@qq.com
-----------------------------------------------*/
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using ProtoBuf.Message;

namespace Battle.View
{
    public class OnceAttackPackageBase {
        public int roundNum;

        public List<OnceHpExport> hpExports = new List<OnceHpExport>();
        public List<OnceAngerExport> angerExports = new List<OnceAngerExport>();
        public List<SpecialStateExport> ssExports = new List<SpecialStateExport>();
        public List<ProtoBuf.Message.RebornExport> rebornExports = new List<RebornExport>();

        public ProtoBuf.Message.CreateMsg createObjs;
        public ProtoBuf.Message.DestroyObj destroyObjs;

        public void DoRebornExport() {
            foreach (var export in rebornExports) {
                var target = BattleViewCtrl.GetInstance().GetBattleCharacter(export.targetUid);
                target.Reborn(export.rebornHealHpNum, export.skills);
            }
        }

        /// <summary>
        /// 结算HPEXPORT
        /// </summary>
        protected void DoHpExport(bool isShowHpBar = true) {
            foreach (var hpExport in hpExports) {
                var bc = BattleViewCtrl.GetInstance().GetBattleCharacter(hpExport.targetUid);
                if (bc != null) {
                    bc.AddHP(hpExport.infValue, isShowHpBar);
                }
            }
        }
        /// <summary>
        /// 显示HPEXPORT
        /// </summary>
        protected void ShowHpExport() {
            foreach (var hpExport in hpExports) {
                var bc = BattleViewCtrl.GetInstance().GetBattleCharacter(hpExport.targetUid);
                if (bc != null) {
                    BattleViewCtrl.GetInstance().ShowWordTip(hpExport);
                    //var newBC = BattleViewCtrl.GetInstance().GetBattleCharacter(
                    //    BattleViewCtrl.GetOppoCamp(bc.camp), 7);
                    //BattleViewCtrl.GetInstance().AddDropFireBall(bc, newBC);
                }
            }
        }

        protected void DoAngerExport() {
            foreach (var angerExport in angerExports) {
                BattleViewCtrl.GetInstance().AddAnger(angerExport.infValue, angerExport.camp);
            }
        }



        protected void DoCreateObjs() {
            foreach (var buf in createObjs.buffers) {
                BattleViewCtrl.GetInstance().AddBattleBuff(buf);
            }
        }

        protected void DoDesotryObjs() {
            DoKillActors();
            DoKillBuffs();
        }

        protected void DoKillActors() {
            foreach (var uid in destroyObjs.actorUids) {
                var bc = BattleViewCtrl.GetInstance().GetBattleCharacter(uid);
                //if (bc != null) { bc.SwitchState(ActorState.Dead); }
                if (bc != null) {
                    if (bc.GetCurrrentStateType() == ActorState.Defend)
                    {
                        bc.isWillDead = true;
                    }
                    else {
                        bc.SwitchState(ActorState.Dead);
                    }
                }
            }
        }
        protected void DoKillBuffs() {
            foreach (var uid in destroyObjs.destroyBufferUids) {
                BattleViewCtrl.GetInstance().RemoveBattleBuff(uid);
            }
        }

        public virtual void NormalDeal() { }
        public virtual void ShowDeal() { }
        public virtual void UltimateDeal() { }
        public virtual void ImmediateDeal() { }

    }

    public class OnceAttackPackage : OnceAttackPackageBase {
        public BattleCharacter sourceBC;
        public BattleSkill sourceSkill;
        public BattleSkillRelease sourceRelease;

        public List<FireMagicStoneExport> msExports = new List<FireMagicStoneExport>();
        public List<AngerMagicStoneExport> asExports = new List<AngerMagicStoneExport>();

        public bool isCombo = false;
        public int comboNum;
        public BattleCamp comboCamp;

        public OnceAttackPackage(ProtoBuf.Message.SkillOnceCast onceCast) {
            sourceBC = BattleViewCtrl.GetInstance().GetBattleCharacter(onceCast.sourceUid);
            sourceSkill = sourceBC.GetSkill((SkillType)onceCast.skillType);
            sourceRelease = sourceSkill.GetSkillRelease(onceCast.releaseId);

            roundNum = onceCast.roundNum;

            if (onceCast.comboInfo != null)
            {
                isCombo = true;
                comboNum = onceCast.comboInfo.comboNum;
                comboCamp = (BattleCamp)(onceCast.comboInfo.camp);
            }
            else
            {
                isCombo = false;
            }

            hpExports = new List<OnceHpExport>();
            foreach (var hp in onceCast.exportMsg.hpExports) {
                hpExports.Add(new OnceHpExport(hp));
            }
            angerExports = new List<OnceAngerExport>();
            foreach (var anger in onceCast.exportMsg.angerExports) {
                angerExports.Add(new OnceAngerExport(anger));
            }
            ssExports = new List<SpecialStateExport>();
            foreach (var sp in onceCast.exportMsg.specialStateExports) {
                ssExports.Add(sp);
            }
            msExports = new List<FireMagicStoneExport>();
            foreach (var ms in onceCast.exportMsg.fireMagicStoneExport) {
                msExports.Add(ms);
            }
            asExports = new List<AngerMagicStoneExport>();
            foreach (var ab in onceCast.exportMsg.angerMagicStoneExport)
            {
                asExports.Add(ab);
            }

            rebornExports = new List<RebornExport>();
            rebornExports.AddRange(onceCast.exportMsg.rebornExports);

            createObjs = (onceCast.exportMsg.createMsg);
            destroyObjs = (onceCast.exportMsg.destroyObjs);

        }

        protected void DoCombo() {
            if (isCombo)
            {
                if (comboCamp == BattleCamp.Attacker && comboNum > 0)
                    BattleManager.Instance.battlePanel.ShowComboNumber(comboNum);
            }
        }

        protected void DoShakeAndPlayBeHitAudio() {
            bool isNeedShake = false;
            foreach (var hpExport in hpExports) {
                if (hpExport.specialType != HpInfSpecialType.Miss) {
                    isNeedShake = true;
                    break;
                }                
            }

            if (isNeedShake)
            {
                CameraController.Instance.Shake(sourceRelease.shakeCameraType);
                if (!string.IsNullOrEmpty(sourceRelease.beHitAudio))
                {
                    AudioManager.Instance.Play(sourceRelease.beHitAudio);
                }
            }
        }

        protected void ShowDropFireBall() {
            foreach (var ms in msExports) {
                var source = BattleViewCtrl.GetInstance().GetBattleCharacter(ms.sourceUid);
                var target = BattleViewCtrl.GetInstance().GetBattleCharacter(ms.targetUid);
                BattleViewCtrl.GetInstance().AddDropFireBall(source, target);
            }
        }

        protected void ShowDropAngerBall()
        {
            foreach (var ab in asExports)
            {
                var source = BattleViewCtrl.GetInstance().GetBattleCharacter(ab.sourceUid);
                BattleViewCtrl.GetInstance().AddDropWaterBall(source, sourceBC);
            }
        }

        protected void ShowSpecialState()
        {
            
            foreach (var st in ssExports)
            {
                var bc = BattleViewCtrl.GetInstance().GetBattleCharacter(st.targetUid);
                if (bc != null && bc.GetCurrrentStateType() == ActorState.Defend)
                {
                    var state = bc.GetCurrentState() as BCDefendState;
                    ActorSpecialState asp = (ActorSpecialState)st.specialState;
                    switch (asp)
                    {
                        case ActorSpecialState.NORMAL:
                            state.Behit();
                            break;
                        case ActorSpecialState.FLOOR:
                            if (sourceRelease.causeSpecialState == ActorSpecialState.FLOOR)
                            {
                                // 强制
                                state.HitFly(true,st.surplusTime);
                            }
                            else {
                                state.HitFly(false, st.surplusTime);
                            }
                            break;
                        case ActorSpecialState.GROUND:
                            if (sourceRelease.causeSpecialState == ActorSpecialState.GROUND)
                            {
                                // 强制
                                state.HitFall(true,st.surplusTime);
                            }
                            else {
                                state.HitFall(false, st.surplusTime);
                            }
                            break;
                        default:
                            break;
                    }
                }
            }
        }


        /// <summary>
        /// 被击特效
        /// </summary>
        protected void ShowBeHitParticle() {
            foreach (var hpExport in hpExports) {
                var target = BattleViewCtrl.GetInstance().GetBattleCharacter(hpExport.targetUid);
                if (target != null) {
                    if (hpExport.specialType != HpInfSpecialType.Miss && hpExport.specialType != HpInfSpecialType.Lifesteal) {
                        target.PlayHitParticle(sourceRelease);
                    }
                }
            }

            return;


        }

        public override void ShowDeal() {
            ShowHpExport();
        }
        
        /// <summary>
        /// 普通结算，正常命中
        /// </summary>
        public override void NormalDeal() {
            DoHpExport();
            ShowHpExport();
            ShowBeHitParticle();
            DoAngerExport();
            ShowSpecialState();
            DoCreateObjs();
            DoDesotryObjs();
            DoCombo();
            ShowDropFireBall();
            ShowDropAngerBall();

            DoShakeAndPlayBeHitAudio();
            DoRebornExport();


        }

        public override void ImmediateDeal() {
            DoHpExport();
            DoAngerExport();
            DoCreateObjs();
            DoDesotryObjs();
            DoCombo();
            DoRebornExport();
        }

        public override void UltimateDeal() {
            DoHpExport(false);
            ShowBeHitParticle();
            DoAngerExport();
            DoCreateObjs();
            DoKillBuffs();
            DoCombo();
            //DoRebornExport();
        }
    }

    public class OnceBuffPackage : OnceAttackPackageBase
    {
        public string buffUID;
        public string buffId;
        public OnceBuffPackage(ProtoBuf.Message.BuffOnceCast onceCast) {
            buffUID = onceCast.sourceUid;
            buffId = onceCast.sourceBuffId;
            hpExports = new List<OnceHpExport>();
            foreach (var export in onceCast.exportMsg.hpExports) {
                hpExports.Add(new OnceHpExport(export));
            }
            angerExports = new List<OnceAngerExport>();
            foreach (var export in onceCast.exportMsg.angerExports) {
                angerExports.Add(new OnceAngerExport(export));
            }
            rebornExports = new List<RebornExport>();
            rebornExports.AddRange(onceCast.exportMsg.rebornExports);
            createObjs = (onceCast.exportMsg.createMsg);
            destroyObjs = (onceCast.exportMsg.destroyObjs);
        }

        protected void ShowBuffHitParticle() {
            //foreach (var export in hpExports) {
            //    var target = BattleViewCtrl.GetInstance().GetBattleCharacter(export.targetUid);
            //    if (target != null) {
            //        var dict = Dict.Blo.DictBuffBlo.GetTableBuff(buffId);
            //        if (!string.IsNullOrEmpty(dict.EffectExport) && !string.IsNullOrEmpty(dict.EffectExportBone)) {
            //            var pd = ParticleData.CreateParticleData(dict.EffectExport, dict.EffectExportBone);
                        
            //            var obj = BattleFactory.SpawnParticle(pd);
            //            target.PlayParticle(obj);
            //            target.ParticleRecovery(obj, true, obj.data.duration);
            //        }
            //    }
            //}
        }

        public override void UltimateDeal() {
            DoHpExport(false);
            DoAngerExport();
            DoCreateObjs();
            DoKillBuffs();
            //DoRebornExport();
        }

        public override void NormalDeal() {
            DoHpExport();
            ShowHpExport();
            DoAngerExport();
            DoCreateObjs();
            DoDesotryObjs();
            DoRebornExport();
            ShowBuffHitParticle();
        }

        public override void ShowDeal() {
            ShowHpExport();
        }
    }
    public class OnceTalentPackage : OnceAttackPackageBase
    {
        public string talentId;
        public OnceTalentPackage(ProtoBuf.Message.TalentOnceCast onceCast) {
            talentId = onceCast.talentId;
            hpExports = new List<OnceHpExport>();
            foreach (var export in onceCast.exportMsg.hpExports)
            {
                hpExports.Add(new OnceHpExport(export));
            }
            angerExports = new List<OnceAngerExport>();
            foreach (var export in onceCast.exportMsg.angerExports)
            {
                angerExports.Add(new OnceAngerExport(export));
            }
            rebornExports = new List<RebornExport>();
            rebornExports.AddRange(onceCast.exportMsg.rebornExports);
            createObjs = (onceCast.exportMsg.createMsg);
            destroyObjs = (onceCast.exportMsg.destroyObjs);
        }

        public override void NormalDeal()
        {
            DoHpExport();
            ShowHpExport();
            DoAngerExport();
            DoCreateObjs();
            DoDesotryObjs();
            DoRebornExport();
        }

        public override void UltimateDeal()
        {
            DoHpExport(false);
            DoAngerExport();
            DoCreateObjs();
            DoKillBuffs();
            //DoRebornExport();
        }

    }



    public class OnceHpExport {
        public string targetUid;
        public double infValue;
        public int bloodNum;
        public HpInfSpecialType specialType;
        public OnceHpExport(ProtoBuf.Message.HpExport hpExport) {
            targetUid = hpExport.targetUid;
            infValue = hpExport.hpExportNum;
            specialType = (HpInfSpecialType)hpExport.specialType;
            //bloodNum = hpExport
        }
    }

    public class OnceAngerExport {
        public BattleCamp camp;
        public double infValue;
        public OnceAngerExport(ProtoBuf.Message.AngerExport angerExport) {
            camp = (BattleCamp)(angerExport.targetCamp);
            infValue = angerExport.angerExportNum;
        }
    }
    

}
